package model.components.links.link;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map.Entry;

public class SdnLink extends Link
{	
	private LinkedHashMap< VirtualLink, BWbackupFlag > virtualLinksBWbackupFlags;
	public LinkedHashMap< VirtualLink, BWbackupFlag > getVirtualLinksBWbackupFlags(){ return virtualLinksBWbackupFlags; }
	public void setVirtualLinksBWbackupFlags( LinkedHashMap< VirtualLink, BWbackupFlag > virtualLinksBWbackupFlags ){ this.virtualLinksBWbackupFlags = virtualLinksBWbackupFlags; }
	
	private int availableBW;
	public int getAvailableBW(){ return availableBW; }
	public void setAvailableBW( int availableBW ){ this.availableBW = availableBW; }
	
	private int distance;
	public int getDistance(){ return distance; }
	public void setDistance( int distance ){ this.distance = distance; }
	
	public SdnLink( String networkName, int number, int bw, int distance )
	{
		super( networkName, SdnLink.class.getSimpleName(), number, bw, Link.SDN_LINK );
		
		this.setVirtualLinksBWbackupFlags( new LinkedHashMap< VirtualLink, BWbackupFlag >() );
		this.setAvailableBW( bw );
		this.setDistance( distance );
	}
	
	@Override
	public SdnLink getCopy()
	{
		SdnLink sdnLink = new SdnLink( this.getNetworkName(), this.getNumber(), this.getBW(), this.getDistance() );
		sdnLink.setNamePrefix( this.getNamePrefix() );
		sdnLink.setName( this.getName() );
		sdnLink.setFirstNode( this.getFirstNode().getCopy() );
		sdnLink.setSecondNode( this.getSecondNode().getCopy() );
		sdnLink.setAvailableBW( this.getAvailableBW() );
		sdnLink.setTimeStamp( this.getTimeStamp() );
		sdnLink.setSelected( this.isSelected() );
		sdnLink.setVirtualLinksBWbackupFlags( this.getCopyVirtualLinksBWbackupFlags() );
		
		return sdnLink;
	}
	private LinkedHashMap< VirtualLink, BWbackupFlag > getCopyVirtualLinksBWbackupFlags()
	{
		LinkedHashMap< VirtualLink, BWbackupFlag > copyVirtualLinksBWbackupFlags = new LinkedHashMap< VirtualLink, BWbackupFlag >();
		Iterator< Entry< VirtualLink, BWbackupFlag > > iterator = this.getVirtualLinksBWbackupFlags().entrySet().iterator();
		
		while( iterator.hasNext() )
		{
			Entry< VirtualLink, BWbackupFlag > virtualLinkBWbackupFlag = iterator.next();
			copyVirtualLinksBWbackupFlags.put( virtualLinkBWbackupFlag.getKey().getCopy(), virtualLinkBWbackupFlag.getValue() );
		}
		
		return copyVirtualLinksBWbackupFlags;
	}
	
	public void put( VirtualLink virtualLink, int bw, int backupFlag )
	{	
		this.getVirtualLinksBWbackupFlags().put( virtualLink, new BWbackupFlag( bw, backupFlag ) );
		this.setAvailableBW( this.getAvailableBW() - bw );
	}
	
	public void remove( VirtualLink removeVirtualLink )
	{
		Iterator< Entry< VirtualLink, BWbackupFlag > > virtualLinksBWbackupFlagsIterator = this.getVirtualLinksBWbackupFlags().entrySet().iterator();
		VirtualLink virtualLink = null;
		int bw = 0;
		
		while( virtualLinksBWbackupFlagsIterator.hasNext() )
		{
			Entry< VirtualLink, BWbackupFlag > virtualLinkBWbackupFlag = virtualLinksBWbackupFlagsIterator.next();
			virtualLink = virtualLinkBWbackupFlag.getKey();
			bw = virtualLinkBWbackupFlag.getValue().getBW();
			 
			if( removeVirtualLink.equals( virtualLink ) )
				break;
		}
		
		this.getVirtualLinksBWbackupFlags().remove( virtualLink );
		this.setAvailableBW( this.getAvailableBW() + bw );
	}
	
	public SdnLink getSoftCopy()
	{
		SdnLink sdnLink = new SdnLink( this.getNetworkName(), this.getNumber(), this.getBW(), this.getDistance() );
		sdnLink.setNamePrefix( this.getNamePrefix() );
		sdnLink.setName( this.getName() );
		sdnLink.setFirstNode( this.getFirstNode().getCopy() );
		sdnLink.setSecondNode( this.getSecondNode().getCopy() );
		sdnLink.setAvailableBW( this.getAvailableBW() );
		sdnLink.setTimeStamp( this.getTimeStamp() );
		sdnLink.setSelected( this.isSelected() );
		
		return sdnLink;
	}
	
}
